package org.xm.sk.controller.dbase;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.data.domain.Page;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.xm.sk.exception.DataNotFoundException;
import org.xm.sk.exception.RequestParamterException;
import org.xm.sk.module.IdBitWorker;
import org.xm.sk.service.data.BaseService;
import org.xm.sk.service.security.XmUser;
import org.xm.sk.vo.Base;
import org.xm.sk.vo.e.ActivityStatus;
import org.xm.sk.vo.e.CouponStatus;
import org.xm.sk.vo.ob.ApplyCoupon;
import org.xm.sk.vo.ob.Coupon4User;
import org.xm.sk.vo.ob.Ids;
import org.xm.sk.vo.ob.MapList;
import org.xm.sk.vo.ob.PageConf;
import org.xm.sk.vo.ob.ResultMsg;
import org.xm.sk.vo.tb.Activity;
import org.xm.sk.vo.tb.Coupon;
import org.xm.sk.vo.tb.Hairdresser;
import org.xm.sk.vo.tb.Image;
import org.xm.sk.vo.tb.Item;
import org.xm.sk.vo.tb.Role;
import org.xm.sk.vo.tb.Shop;
import org.xm.sk.vo.tb.User;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;

@SuppressWarnings("unchecked")
@Api(tags = { "coupon" })
@RestController
@RequestMapping(value = "/coupons")
public class CouponController {

    @Autowired
    private MessageSource messages;
    @Autowired
    private BaseService<Coupon> couponService;
    @Autowired
    private BaseService<Activity> activityService;
    @Autowired
    private BaseService<Shop> shopService;
    @Autowired
    private BaseService<Hairdresser> hairdresserService;
    @Autowired
    private BaseService<User> userService;
    @Autowired
    private IdBitWorker idBitWorker;

    @ApiOperation(value = "创建优惠券", notes = "根据coupon对象创建优惠券，使用此接口需要ADMIN权限")
    @ApiImplicitParam(name = "coupon", value = "优惠券详细实体coupon", required = true, dataType = "Coupon")
    @PreAuthorize("hasRole('ADMIN')")
    @RequestMapping(value = "", method = RequestMethod.POST)
    public ResultMsg add(@RequestBody Coupon coupon) {
        Coupon u = null;
        if (null != coupon.getId() && 0 < coupon.getId())
            u = (Coupon) couponService.findById(coupon.getId());
        else
            u = coupon;
        u.setShop(null);
        u.setShopName(null);
        u.setHairdresser(null);
        u.setHairdresserName(null);
        u.setUser(null);
        u.setUserName(null);
        u.setActivity(null);
        u.setActivityName(null);
        if (null != coupon.getShopId() && 0 < coupon.getShopId()) {
            Shop shop = (Shop) shopService.findById(coupon.getShopId());
            if (Base.isValid(shop)) {
                u.setShop(shop);
                u.setShopName(shop.getName());
            }
        }
        if (null != coupon.getHairdresserId()
                && 0 < coupon.getHairdresserId()) {
            Hairdresser hairdresser = (Hairdresser) hairdresserService
                    .findById(coupon.getHairdresserId());
            if (Base.isValid(hairdresser)) {
                u.setHairdresser(hairdresser);
                u.setHairdresserName(hairdresser.getName());
            }
        }
        if (null != coupon.getUserId() && 0 < coupon.getUserId()) {
            User user = (User) userService.findById(coupon.getUserId());
            if (Base.isValid(user)) {
                u.setUser(user);
                u.setUserName(user.getName());
            }
        }
        if (null != coupon.getActivityId() && 0 < coupon.getActivityId()) {
            Activity activity = (Activity) activityService
                    .findById(coupon.getActivityId());
            if (Base.isValid(activity)) {
                u.setActivity(activity);
                u.setActivityName(activity.getName());
            }
        }
        if (null != coupon.getStatus())
            u.setStatus(coupon.getStatus());
        if (null != u.getId() && 0 < u.getId())
            couponService.update(u);
        else
            couponService.add(u);
        return new ResultMsg("200",
                messages.getMessage("success", null, "SUCCESS", null),
                new Date());
    }

    @ApiIgnore()
    @ApiOperation(value = "删除优惠券", notes = "根据URI的id来指定删除对象")
    @ApiImplicitParam(name = "id", value = "优惠券ID", required = true, paramType = "path", dataType = "int")
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public ResultMsg delete(@PathVariable Integer id) {
        couponService.delete(id);
        return new ResultMsg("200",
                messages.getMessage("success", null, "SUCCESS", null),
                new Date());
    }

    @ApiOperation(value = "删除优惠券", notes = "根据POST的id列表来指定删除对象，可批量")
    @ApiImplicitParam(name = "ids", value = "优惠券ID集", required = true, dataType = "Ids")
    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
    public ResultMsg Batchdelete(@RequestBody Ids ids) {
        couponService.delete(ids.getIds());
        return new ResultMsg("200",
                messages.getMessage("success", null, "SUCCESS", null),
                new Date());
    }

    @ApiIgnore()
    @ApiOperation(value = "更新优惠券详细信息", notes = "根据URI的id来指定更新对象，并根据传过来的coupon信息来更新优惠券详细信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "优惠券ID", required = true, paramType = "path", dataType = "int"),
            @ApiImplicitParam(name = "coupon", value = "待更新的优惠券详细实体coupon", required = true, dataType = "Coupon") })
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    public ResultMsg update(@PathVariable Integer id,
            @RequestBody Coupon coupon) throws DataNotFoundException {
        Coupon u = (Coupon) couponService.findById(id);
        if (null == u) {
            throw new DataNotFoundException(Coupon.class.getName());
        }
        coupon.setId(id);
        couponService.update(coupon);
        return new ResultMsg("200",
                messages.getMessage("success", null, "SUCCESS", null),
                new Date());
    }

    @ApiIgnore()
    @ApiOperation(value = "获取优惠券详细信息", notes = "根据URI的id来获取优惠券详细信息")
    @ApiImplicitParam(name = "id", value = "优惠券ID", required = true, paramType = "path", dataType = "int")
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public Coupon load(@PathVariable Integer id) throws DataNotFoundException {
        Coupon u = (Coupon) couponService.findById(id);
        if (null == u) {
            throw new DataNotFoundException(Coupon.class.getName());
        }
        return u;
    }

    @ApiOperation(value = "获取优惠券列表", notes = "根据提交的分页信息列出所以优惠券信息")
    @ApiImplicitParam(name = "pageConf", value = "分页信息实体", required = true, dataType = "PageConf")
    @RequestMapping(value = { "/list" }, method = RequestMethod.POST)
    public MapList<Coupon> list(@RequestBody PageConf pageConf) {
        List<Coupon> u = null;
        Long allCount = null;
        Object o = couponService.findAllByPage(pageConf);
        if (o instanceof Page) {
            allCount = ((Page<Coupon>) o).getTotalElements();
            u = ((Page<Coupon>) o).getContent();
        } else {
            allCount = (long) ((List<Coupon>) o).size();
            u = (List<Coupon>) o;
        }
        for (Coupon c : u) {
            if (null != c.getShop())
                c.setShopId(c.getShop().getId());
            if (null != c.getHairdresser())
                c.setHairdresserId(c.getHairdresser().getId());
            if (null != c.getUser()) {
                c.setUserId(c.getUser().getId());
                if (null != c.getUser().getNickname()
                        && 0 < c.getUser().getNickname().trim().length()
                        && null != c.getUser().getPhone()
                        && 0 < c.getUser().getPhone().trim().length())
                    c.setUserName(c.getUser().getNickname() + ":"
                            + c.getUser().getPhone());
                else if (null != c.getUser().getPhone()
                        && 0 < c.getUser().getPhone().trim().length())
                    c.setUserName(c.getUser().getPhone());
                else if (null != c.getUser().getNickname()
                        && 0 < c.getUser().getNickname().trim().length())
                    c.setUserName(c.getUser().getNickname());
                else
                    c.setUserName(c.getUser().getName());
            }
            if (null != c.getActivity()) {
                c.setActivityId(c.getActivity().getId());
                c.setActivityName(c.getActivity().getName());
            }
            if (null != c.getBoder())
                c.setOrdernum(c.getBoder().getOrdernum());
        }
        return new MapList<Coupon>(allCount, u);
    }

    // --------------------- 业务具体接口 ---------------------

    @ApiOperation(value = "获取用户优惠券列表", notes = "根据提交的分页信息列出用户所有的优惠券信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "size", value = "每页数量", required = true, paramType = "path", dataType = "int"),
            @ApiImplicitParam(name = "page", value = "页码", required = true, dataType = "int", paramType = "path") })
    @RequestMapping(value = {
            "/list4user/{size}/{page}" }, method = RequestMethod.GET)
    public MapList<Coupon4User> list4User(@PathVariable Integer size,
            @PathVariable Integer page) throws RequestParamterException {
        if (null == size || null == page || 1 > size || 0 > page) {
            throw new RequestParamterException();
        }
        Map<String, Object> map = new HashMap<String, Object>();
        Page<Coupon4User> coupon4User = null;
        XmUser xmUser = (XmUser) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        if (0 == xmUser.getHairdresserid()) {
            map.put("userid", xmUser.getUserid());
            coupon4User = (Page<Coupon4User>) couponService
                    .findAllByPage(new PageConf(page, size), map);
        } else {
            map.put("hairdresserId", xmUser.getHairdresserid());
            coupon4User = (Page<Coupon4User>) couponService
                    .findAllByPage(new PageConf(page, size), map);
        }
        Long allCount = coupon4User.getTotalElements();
        List<Coupon4User> list = coupon4User.getContent();
        for (Coupon4User c : list) {
            Activity a = (Activity) activityService.findById(c.getActivityId());
            Set<Integer> imageIds = new HashSet<Integer>(0);
            for (Image i : a.getImages()) {
                imageIds.add(i.getId());
            }
            c.setImageIds(imageIds);
            for (Shop shop : a.getShops()) {
                c.getShopIds().add(shop.getId());
                c.getShopNames().add(shop.getName());
            }
            for (Item item : a.getItems()) {
                c.getItemIds().add(item.getId());
                c.getItemNames().add(item.getName());
            }
        }
        return new MapList<Coupon4User>(allCount, list);
    }

    @ApiIgnore()
    @ApiOperation(value = "发型师申请优惠券", notes = "发型师申请自己所属的个人优惠券，待生效")
    @ApiImplicitParam(name = "applyCoupon", value = "发型师申请优惠券必填信息实体ApplyCoupon", required = true, dataType = "ApplyCoupon")
    @PreAuthorize("hasAnyRole('ADMIN', 'HAIRDRE')")
    @Transactional
    @RequestMapping(value = {
            "/apply4hairdresser_x" }, method = RequestMethod.POST)
    public ResultMsg apply4hairdresser(@RequestBody ApplyCoupon applyCoupon)
            throws RequestParamterException {
        XmUser xmUser = (XmUser) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        if (0 == xmUser.getHairdresserid()) {
            throw new RequestParamterException("当前用户非发型师用户，查无发型师信息");
        }
        Hairdresser hairdresser = (Hairdresser) hairdresserService
                .findById(xmUser.getHairdresserid());
        Activity a = new Activity();
        a.setConditions(applyCoupon.getConditions());
        a.setCount(1);
        a.setDeadline(applyCoupon.getDeadline());
        a.setName(applyCoupon.getName());
        a.setPrice(applyCoupon.getPrice());
        a.setScope(applyCoupon.getScope());
        a.setStatus(ActivityStatus.ENDDING);
        a = activityService.add(a);
        Coupon o = new Coupon();
        o.setCouponnum(idBitWorker.nextCouponNum());
        o.setHairdresserName(hairdresser.getName());
        o.setHairdresser(hairdresser);
        o.setName(applyCoupon.getName());
        o.setShop(hairdresser.getShop());
        o.setShopName(hairdresser.getShop().getName());
        o.setStatus(CouponStatus.EFFECTING);
        o.setActivity(a);
        couponService.add(o);
        return new ResultMsg("200",
                messages.getMessage("success", null, "SUCCESS", null),
                new Date());
    }

    @ApiIgnore()
    @ApiOperation(value = "发型师优惠券转让", notes = "根据提交的优惠券ID和转让对象实体实现发型师优惠券转让给客户")
    @PreAuthorize("hasAnyRole('ADMIN', 'HAIRDRE')")
    @RequestMapping(value = {
            "/mkover_x/{id}/{username}" }, method = RequestMethod.GET)
    public ResultMsg makeOver(@PathVariable Integer id,
            @PathVariable String username) throws RequestParamterException {
        if (null == id || 0 == id || null == username
                || 0 == username.trim().length()) {
            throw new RequestParamterException();
        }
        XmUser xmUser = (XmUser) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        if (0 == xmUser.getHairdresserid()) {
            throw new RequestParamterException("当前用户非发型师用户，查无发型师信息");
        }
        Coupon c = (Coupon) couponService.findById(id);
        if (null == c || c.getStatus() != CouponStatus.NORMAL || xmUser
                .getHairdresserid() != c.getHairdresser().getId().intValue()
                || null != c.getUser()) {
            throw new RequestParamterException("无效优惠券ID");
        }
        Set<User> users = (Set<User>) userService.findByName(username);
        if (null == users || users.isEmpty()) {
            throw new RequestParamterException("请输入正确的转让用户名");
        }
        User u = users.iterator().next();
        boolean isHairdre = false;
        Iterator<Role> roles = u.getRoles().iterator();
        while (roles.hasNext()) {
            Role r = roles.next();
            if (r.getName().equals("ROLE_BOSS")
                    || r.getName().equals("ROLE_HAIRDRE")) {
                isHairdre = true;
                break;
            }
        }
        if (isHairdre) {
            throw new RequestParamterException("不能转赠优惠券，转让对方身份只能是客户");
        }
        c.setUser(u);
        c.setUserName(u.getName());
        couponService.update(c);
        return new ResultMsg("200",
                messages.getMessage("success", null, "SUCCESS", null),
                new Date());
    }

}
